#!/usr/bin/env perl
#
# $Id: addip.pl 7557b5d4d82b 2012/12/02 09:07:16 pgurumur $
# Copyright (c) 2009 Prabhu Gurumurthy <pgurumur@gmail.com>
# 
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
# 
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
use strict;
use warnings;

use Getopt::Long;
use NetAddr::IP;

use lib "/srv/www/netdot/lib";
use Netdot::Model;

Getopt::Long::Configure("default", "bundling");
push my @prog, split(/\//, $0);
my $program = $prog[$#prog];

my $arg = int(scalar(@ARGV));
my %options = ();

sub usage {
   printf("%s options\n", $program);
   print "\t--help | -?     [ prints this help ]\n";
   print "\t--address | -a  [ IPv4/IPv6 address ]\n";
   print "\t--status | -s   [ Choose one from the following ]\n";
   print "\t\t dynamic, static, container, reserved, subnet\n";
   print "\t--used | -u   [ Choose an entity to associate this subnet ]\n";
   print "\t--description | -d [ Description for this subnet ]\n";
   exit(0);
}

sub main {
   GetOptions(\%options, "help|?", "address|a=s", "status|s=s", "used|u=s",
      "description|d=s") or usage();
   usage() if $options{help};

   my $address = undef;
   my $addnum = 0;
   if ($options{address}) {
      $address = new NetAddr::IP $options{address};
      my ($numeric, $value) = $address->numeric();
      $addnum = $numeric;
   }

   if (defined($address)) {
      my $status = undef;
      if (defined($options{status})) {
         $status = $options{status};
         die "Unrecognized status: $options{status}\n" unless(ucfirst(
               $options{status}) =~ /^Dynamic|Static|Container|Reserved|Subnet$/);
      }
      else {
         if ($address->version() == 4) {
            $status = $address->masklen() == 32 ? "Static" : "Subnet";
         }
         elsif ($address->version() == 6) {
            $status = $address->masklen() == 128 ? "Static" : "Subnet";
         }
      }

      my $owner = Entity->find_or_create({id => 25});
      my $usedby = Entity->find_or_create(name => $options{used});
      if (my $ip = Ipblock->search(address => $address->addr(),
            prefix => $address->masklen())->first) {
         printf("IP: %s exists, updating.... ". $ip->get_label);
         $ip->update({
               status      => ucfirst($status),
               owner       => $owner,
               used_by     => $usedby,
               description => $options{description},
            });
         printf("done\n");
      }
      else {
         my $newip = undef;
         eval { $newip = Ipblock->insert({
                  address        => $address->addr(),
                  prefix         => $address->masklen(),
                  status         => ucfirst($status),
                  owner          => $owner,
                  used_by        => $usedby,
                  description    => $options{description},
                  no_update_tree => 1,
               });
         };

         if (my $err = $@) {
            die "$program ERROR: $err\n";
         }
         else {
            printf("Inserted: %s\n", $newip->get_label);
         }
      }

      Ipblock->build_tree(4);
      Ipblock->build_tree(6);
   }
}

if ($arg <= 1) {
   usage();
}
else {
   main();
}

